package cylons;

import java.util.Stack;

import static cylons.Move.Mode.*;

/**
 * Implements the algorithm used to sink (all) ships that are adjacent to a hit square
 *
 * @author mcox
 */
public class TargetingSystem implements BattleShipSystem {
    Stack<Move> shotStack;

    public TargetingSystem() {
        shotStack = new Stack<Move>();
    }

    /**
     * On the initial hit we will push onto our shot stack all empty adjacent peg squares. As progressive hits are made
     * their neighboring empty squares are pushed onto the stack. Each shot pushed onto the stack will leave the mode
     * in targeting, save for the first move which will relinquish control.
     * @param row
     * @param col
     * @return
     */
    public Move makeMove(char [][] pegBoard, int row, int col) {
        if (pegBoard[row][col] == 'H') {
            addShot(pegBoard, row - 1, col);
            addShot(pegBoard, row, col + 1);
            addShot(pegBoard, row + 1, col);
            addShot(pegBoard, row, col - 1);
        }

        if (shotStack.isEmpty()) {
            return null;
        }

        return shotStack.pop();
    }

    /**
     * Add the shot if the square is empty and on the board. If the shot is the first one added to the stack set the
     * mode to return control to the hunting algorithm.
     * @param row
     * @param col
     * @return
     */
    private boolean addShot(char [][] pegBoard, int row, int col) {
        if (!shotStack.contains(new Move(row, col, TARGET))
                && row >= 0 && row < pegBoard[0].length && col >= 0 && col < pegBoard.length) {
            if (pegBoard[row][col] == ' ') {
                if (shotStack.isEmpty()) {
                    shotStack.add(new Move(row, col, HUNT));
                } else {
                    shotStack.add(new Move(row, col, TARGET));
                }

                return true;
            }
        }

        return false;
    }

}
